package org.zxy.base.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import org.zxy.auth.domain.Permission;
import org.zxy.auth.mapper.PermissionMapper;
import org.zxy.base.annotation.RonghuaPermission;
import org.zxy.base.service.IAutoScanPermissionService;
import org.zxy.base.util.ClassUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

@Service
public class AutoScanPermissionServiceImpl implements IAutoScanPermissionService {
    @Value("${scan.paths}")
    private String paths;
    @Value("${scan.tages}")
    private boolean tages;

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public void scan() {
        System.out.println("扫描开始");
        //是否要扫描Controller
        if (!tages) return;
        //拿Controller
        List<Class> controllerList = ClassUtils.getAllClassName(paths);
        //遍历Controller
        for (Class controllerClass : controllerList) {//遍历Controller类
            //获取有权限注解的类
            RonghuaPermission annotation = (RonghuaPermission) controllerClass.getAnnotation(RonghuaPermission.class);
            if (annotation == null) continue;
            Permission parent = new Permission();
            //维护父级资源
            parent.setName(annotation.name());
            parent.setDescs(annotation.desc());
            RequestMapping requestMapping = (RequestMapping) controllerClass.getAnnotation(RequestMapping.class);
            parent.setUrl(requestMapping.value()[0]);
            parent.setSn(controllerClass.getSimpleName());
            //查父级菜单
            Permission permission = permissionMapper.selectBySn(parent.getSn());
            if (permission != null) {
                parent.setId(permission.getId());
                permissionMapper.update(parent);
            } else {
                permissionMapper.insert(parent);
            }
            //拿到Controller类的方法
            Method[] methods = controllerClass.getMethods();
            for (Method method : methods) {//遍历controller类里的方法
                //获取有权限注解的方法
                RonghuaPermission methodAnnotation = method.getAnnotation(RonghuaPermission.class);
                if (methodAnnotation == null) continue;
                Permission child = new Permission();
                child.setName(methodAnnotation.name());
                child.setDescs(methodAnnotation.desc());
                child.setSn(parent.getSn() + ":" + method.getName());
                child.setParentId(parent.getId());
                String childUrl = getChildUrl(method);
                child.setUrl(parent.getUrl() + childUrl);
                Permission childPermission = permissionMapper.selectBySn(child.getSn());
                if (childPermission != null) {
                    child.setId(childPermission.getId());
                    permissionMapper.update(child);
                } else {
                    permissionMapper.insert(child);
                }
            }
        }
    }

    private String getChildUrl(Method method) {
        RequestMapping annotation = method.getAnnotation(RequestMapping.class);
        if (annotation != null) {
            return annotation.value().length > 0 ? annotation.value()[0] : "";
        }
        GetMapping getMapping = method.getAnnotation(GetMapping.class);
        if (getMapping != null) {
            return getMapping.value().length > 0 ? getMapping.value()[0] : "";
        }
        PutMapping putMapping = method.getAnnotation(PutMapping.class);
        if (putMapping != null) {
            return putMapping.value().length > 0 ? putMapping.value()[0] : "";
        }
        DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
        if (deleteMapping != null) {
            return deleteMapping.value().length > 0 ? deleteMapping.value()[0] : "";
        }
        PostMapping postMapping = method.getAnnotation(PostMapping.class);
        if (postMapping != null) {
            return postMapping.value().length > 0 ? postMapping.value()[0] : "";
        }
        PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
        if (patchMapping != null) {
            return patchMapping.value().length > 0 ? patchMapping.value()[0] : "";
        }
        return null;
    }
}
